<?php

namespace app\api\controller;

use app\common\business\Cate;
use app\common\business\Goods;
use app\common\business\Banner;
use app\common\business\Group;
use app\common\business\Member;
use app\common\business\Membercard;
use app\common\business\OrderGoods;
use app\common\business\Orders;
use app\common\business\Wechat;
use app\common\lib\ArrClass;
use app\common\lib\Show;
use app\common\lib\Status;
use app\common\lib\Str;
use app\common\model\MallGoods;
use app\common\model\MallGroupsGoods;
use app\common\model\MallGroupsOrder;
use app\common\model\MallGroupsTeam;
use app\common\model\MallManager;
use app\common\model\MemberPaylog;
use EasyWeChat\Factory;
use think\cache\driver\Redis;
use think\Exception;
use think\facade\Log;

class Index extends Base
{
    /**
     * 首页接口
     * @return \think\response\Json
     */
    public function getIndexList()
    {
        $latitude = $this->request->param('latitude', '0', 'trim');
        $longitude = $this->request->param('longitude', '0', 'trim');
        $type = $this->request->param('type', 2, 'intval');
        $where = [
            ['status', '=', Status::mysql_normal],
            ['type', '=', $type]
        ];
        try {
            $banner = (new Banner())->getBannerByList($where, "id,images as img_url");
            // 附近拼团商品
            $nearbygoods = (new Group())->getShowIndexGroupsGoods([['status','=',1],['isindex','=',1]],'id,logo,title,short_title,groupnum,groupsprice,price,mendian',3,$latitude,$longitude);
            $groupgoods =(new Group())->getShowIndexGroupsGoods([['status','=',1],['isindex','=',1]],'id,logo,title,short_title,groupnum,groupsprice,price,mendian',20,$latitude,$longitude);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, $e->getMessage());
        }
       
        return Show::json_show(Status::mini_normal, "ok", [
            "banner" => $banner, // 轮播图
            'goods' => $nearbygoods,   // 附近拼团商品
            "groupgoods" =>$groupgoods // 拼团商品
        ]);
    }

    /**
     * 商城页面
     * @return \think\response\Json
     */
    public function getShopList(){
        $type = $this->request->param('type', 3, 'intval');
        $openid = $this->request->param('openid', '', 'trim');
        $where = [
            ['status', '=', Status::mysql_normal],
            ['type', '=', $type]
        ];
        try {
            $banner = (new Banner())->getBannerByList($where, "id,images as img_url");
            $cates =(new Cate())->getCateList([['status','=',1],['type','=',1]],'id,title,image');
            $where2 = [['isrecommend', '=', 1], ['status', '=', 1],['apply_status','=',1]];
            $fjgoods = (new Goods())->getallGoodslist($openid,$where2, 'id,logo,goods_price,market_price,title,title_desc,virtual_sales');
            $where3 = [['ishot', '=', 1], ['status', '=', 1],['apply_status','=',1]];
            $hotgoods = (new Goods())->getallGoodslist($openid,$where3, 'id,logo,goods_price,market_price,title,title_desc,virtual_sales');

        }catch (\Exception $e){
            return Show::json_show(Status::mini_error, $e->getMessage());
        }

        return Show::json_show(Status::mini_normal, "ok", [
            "banner" => $banner,
            'cat' =>$cates,
            'recommendgoods' => $fjgoods,
            'hotgoods' =>$hotgoods
        ]);
    }

    public function getShopListByall(){
        $openid = $this->request->param('openid', '', 'trim');
        $page = $this->request->param('page', 1, 'intval');
        $where = [
            ['status', '=', Status::mysql_normal]
            ,['apply_status','=',1]
        ];
        try {

            $hotgoods = (new Goods())->getallGoodslistByNew($openid,$where,$page,'id,logo,goods_price,market_price,title,title_desc,virtual_sales');

        }catch (\Exception $e){
            return Show::json_show(Status::mini_error, $e->getMessage());
        }

        return Show::json_show(Status::mini_normal, "ok", [
            'hotgoods' =>$hotgoods
        ]);
    }


    /**
     * 拼团商品列表
     * @return \think\response\Json|void
     */
    public function getGroupGoods(){
        $page =$this->request->param('page','1','intval');
        $latitude = $this->request->param('latitude', '0', 'trim');
        $longitude = $this->request->param('longitude', '0', 'trim');
        $keyword =$this->request->param('keyword','','trim'); //搜索参数
        $where = [
            ['status', '=', Status::mysql_normal],
        ];
        if($keyword){
            $where[] =['title','like','%'.$keyword.'%'];
        }
        try{
            $groupgoods =(new Group())->getShowGroupsGoods($page,$where,$longitude,$latitude);
            $banner  = (new Banner())->getBannerByList($where, "id,images as img_url");
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error, $e->getMessage());
        }
        return Show::json_show(Status::mini_normal, "ok", [
            'groupgoods' =>$groupgoods,
            'banner' =>$banner
        ]);
    }


    /**
     * 分类商品
     * @return void
     */
    public function catByGoods(){
        $catid =$this->request->param('catid','0','intval');
        $openid =$this->request->param('openid','','trim');
        $where=[['id','=',$catid],['status','=',1]];
        try {
            $catinfo =(new Cate())->getCateInfo($where,'id,title,cat_img');
            $where2=[['cate_id','=',$catid],['status','=',1]];
            $categoods =(new Goods())->getallGoodslist($openid,$where2,'id,logo,goods_price,market_price,title,title_desc,virtual_sales');
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        return Show::json_show(Status::mini_normal, "ok", [
            "catinfo" => $catinfo,
            'cat' =>$categoods
        ]);
    }

    /**
     * 商品详情
     * @return \think\response\Json
     */
    public function goodsDetail(){
        $id =$this->request->param('id','0','intval');
        $openid =$this->request->param('openid','','trim');
        $where=[['id','=',$id],['status','=',1]];
        try {
            $ginfo =(new Goods())->getGoodsInfo($openid,$where,'id,title,title_desc,goods_price,market_price,virtual_sales,clicknum,stock,images,description');
            $goodsinfo =$ginfo;
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,$e->getMessage());
        }
        if($goodsinfo){
            $ginfo->save(array('clicknum'=>$ginfo['clicknum']+1));
        }else{
            return Show::json_show(Status::mini_error,'商品不存在');
        }
        if($goodsinfo['clicknum']>999){
            $goodsinfo['clicknum'] ='999+';
        }
        return Show::json_show(Status::mini_normal, "ok", [
            "ginfo" => $goodsinfo
        ]);
    }

    /**
     * 拼团商品详情
     * @return \think\response\Json
     */
    public function getGroupGoodsdetail(){
        $id =$this->request->param('id','0','intval');
        $where=[['id','=',$id],['status','=',1]];
        try {
            $ginfo =(new Group())->getGoodsInfo($where,'id,title,short_title as title_desc,groupsprice as goods_price,singleprice,price as market_price,sales,groupnum,goodsdesc,groupdesc,goodsnum,clicknum,stock,total_stock,sales,thumb as images,content,mendian,endtime');
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }
        if($ginfo){
            $ginfo['mendian'] =json_decode($ginfo['mendian'],true);
            $ginfo['mendian'] = $ginfo['mendian']??[];
            if($ginfo['endtime']<=time()){
                $ginfo['isend'] =1;
            }else{
                $ginfo['isend']=0;
            }
        }else{
            return Show::json_show(Status::mini_error,'商品不存在');
        }
        return Show::json_show(Status::mini_normal, "ok", [
            "ginfo" => $ginfo
        ]);
    }


    /**
     * 记录商品点击次数
     * @return void
     */
    public function clickByGoods(){
        $id =$this->request->param('id','0','intval');
        $openid =$this->request->param('openid','','trim');
        $goodsinfo= (new Goods())->getGoodsInfo($openid,[['id','=',$id]],'id,clicknum');
        if(!$goodsinfo){
            return Show::json_show(Status::mini_error,'商品不存在');
        }else{
            $clicknum =$goodsinfo['clicknum']+1;
            $result= $goodsinfo->save(array('clicknum'=>$clicknum));
            if($clicknum>=999){
                $clicknum ='999+';
            }
            return Show::json_show(Status::mini_normal, "ok", [
                "clicknum" => $clicknum
            ]);
        }
    }

    /**
     * 经纬度转地址
     * @return \think\response\Json
     */
    public function getLoadtionToName(){
        $lat =$this->request->param('lat','','trim');
        $lng=$this->request->param('lng','','trim');
        // 腾讯经纬度换百度经纬度
        $wxurl = 'http://api.map.baidu.com/geoconv/v1/?coords='.$lng.','.$lat.'&ak=2O6lG6GM0gjq2CmD5ni255359WHGe3bA&output=json';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $wxurl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        $r = curl_exec($ch);
        curl_close($ch);
        $addr = json_decode($r);
        $addr=object_array($addr);
        // 百度经纬度换地址
        $baiduurl='http://api.map.baidu.com/reverse_geocoding/v3/?ak=2O6lG6GM0gjq2CmD5ni255359WHGe3bA&output=json&coordtype=wgs84ll&location='.$addr['result'][0]['y'].','.$addr['result'][0]['x'];
        $che = curl_init();
        curl_setopt($che, CURLOPT_URL, $baiduurl);
        curl_setopt($che, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        $rr = curl_exec($che);
        curl_close($che);
        $addrresult = json_decode($rr);
        $addrArray=object_array($addrresult);
        return Show::json_show(Status::mini_normal, "ok", [
            "location" => $addrArray['result']['formatted_address'],
        ]);
    }

    /**
     * 后台会员卡设置商品价格  搜索商品
     * @return \think\response\Json
     */
    public function getGoodsSearchResult(){
        $keyword =$this->request->param('keyword','','trim');
        try{
            $goods =(new MallGoods())->field('id,title as name')->where([['title','like','%'.$keyword.'%'],['status','=',1]])->select()->toArray();
        }catch (\Exception $e){
            return Show::json_show(Status::mini_error,'查询失败');
        }

        if($goods){
            foreach ($goods as $k=>$v){
                $goods[$k]['selected'] =false;
                $goods[$k]['disabled'] =false;
                $goods[$k]['value'] =$v['id'];
            }
        }

        return Show::json_show(Status::mini_normal, "ok", [
            "goods" => $goods ?? []
        ]);
    }


    public function getRegionSearchResult(){
        $keyword =$this->request->param('keyword','','trim');
        $url="https://apis.map.qq.com/ws/place/v1/suggestion/?region=&keyword=".$keyword."&key=KQ7BZ-GAMWD-5TJ46-HST4A-H66BT-YPFCX";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
        $r = curl_exec($ch);
        curl_close($ch);
        $addr = json_decode($r);
        $addresslists =[];
        if(object_array($addr)['data']){
            $addresslist =object_array($addr)['data'];
            foreach ($addresslist as $k=>$v){
                $addresslists[$k]['name'] =$v['title'];
                $addresslists[$k]['selected'] =false;
                $addresslists[$k]['disabled'] =false;
                $addresslists[$k]['value'] =$v['location']['lat'].','.$v['location']['lng'];
            }
        }

        return Show::json_show(Status::mini_normal, "ok", [
            "location" => $addresslists
        ]);
    }


    /**
     * 拼团到期未完成自动退款
     * @return \think\response\Json
     * @throws Exception
     * @throws \ReflectionException
     */
    public function groupToBackOrderRefund(){
        try{
            $orders = (new MallGroupsGoods())->alias('g')
                ->field('o.*')
                ->join('mall_groups_order o','o.goods_id=g.id')
                ->where("g.endtime<'".time()."' and o.success=0 and heads=1")
                ->select()->toArray();
        }catch(\Exception $e){
            return Show::json_show(Status::mini_error, '查询失败');
        }
        // 微信支付
        if(!empty($orders)){
//            foreach($orders as $k=>$order) {
//                if ($order['paytype'] == 1) {
//                    $refundno = Str::RandomStr();
//                    $objClass = ArrClass::payAttr();
//                    $obj = ArrClass::initClass('wx', $objClass, [], true);
//                    // 商城支付记录
//                    $paylog = (new \app\common\business\MemberPaylog())->getByOrderTypeId($order['id'], 4);
//                    if($paylog){
//                        $result = $obj->refund($paylog['ordersn'], $refundno, intval($order['payprice']*100), intval($order['payprice']*100), ['refund_desc' => '同城生活商城拼团退款']);
//                        if ($result['return_code'] == 'SUCCESS') {
//                            if ($result['result_code'] == 'SUCCESS') {
//                                (new MallGroupsOrder())->where("id='" . $order['id'] . "'")->save(array('status' => 4, 'refundtime' => time()));
//                            }
//                        }
//                    }
//                }else{
//                    // 余额支付
//                    (new Member())->saveAccoutLog($order['openid'],$order['payprice'],4,'拼团未完成结束退还');
//                    (new MallGroupsOrder())->where("id='" . $order['id'] . "'")->save(array('status' => 4, 'refundtime' => time()));
//                }
//            }
        }

        return Show::json_show(Status::mini_normal, "返回成功", [
        ]);
    }

    /**
     * 微信支付回调
     * @return void
     */
    public function paynotify(){
        $app = Factory::payment(config('wechat.pay'));
        $response = $app->handlePaidNotify(function($message, $fail){
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单

            $order = (new \app\common\business\MemberPaylog())->getByOrderId($message['out_trade_no']);
            if (!$order || $order['status']==1) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
            }
            if($message['attach'] == 'payshop'){ // 商城订单支付
                $shoporder = (new Orders())->getByOrderIds($order['order_id']);
                ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付 /////////////
                if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                    // 用户是否支付成功
                    if ($message['result_code'] === 'SUCCESS') {
                        $orderdata=array('paytime'=>time(),'status'=>1);
                        $order->save($orderdata); // 保存订单
                        // 更新商城订单
                        $shoporder->save(array('paytime'=>time(),'orderstatus'=>1));
                        // 更新销量
                        $goodslist =(new OrderGoods())->getByOrderGoodsList($order['order_id']);
                        foreach ($goodslist as $kk=>$vv){
                            (new MallGoods())->where("id='".$vv['goods_id']."'")->save(array('sales'=>$vv['sales']+$vv['total'],'virtual_sales'=>$vv['virtual_sales']+$vv['total'],'stock'=>$vv['stock']-$vv['total']));
                        }



                        // 用户支付失败
                    } elseif ($message['result_code'] === 'FAIL') {
                        Log::error("用户支付失败");
                    }
                } else {
                    Log::error("通信失败");
                    return $fail('通信失败，请稍后再通知我');
                }

            }elseif($message['attach'] == 'paycard'){ // 会员卡支付

                ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付 /////////////
                if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                    // 用户是否支付成功
                    if ($message['result_code'] === 'SUCCESS') {
                        $orderdata=array('paytime'=>time(),'status'=>1);
                        $order->save($orderdata); // 保存订单

                        // 更新用户会员卡等级
                        $cardinfo=(new Membercard())->getMembercardInfo($order['card_id']);
                        $userinfo=(new Wechat())->getOpenidById($order['openid']);
                        if($userinfo['overtime']>=time()){
                            $endtime =intval($cardinfo['month']*30*24*3600 + $userinfo['overtime']);
                        }else{
                            $endtime =intval($cardinfo['month']*30*24*3600 + time());
                        }
                        $wdata =array('openid'=>$order['openid'],'usertype'=>$order['card_id'],'overtime'=>$endtime,'ret_data'=>$userinfo['ret_data']);
                        (new Wechat())->WechatByOpenid($wdata);

                        // 用户支付失败
                    } elseif ($message['result_code'] === 'FAIL') {
                        Log::error("用户支付失败");
                    }
                } else {
                    Log::error("通信失败");
                    return $fail('通信失败，请稍后再通知我');
                }
            }elseif($message['attach']=='grouppay'){//拼团支付
                $grouporder = (new Group())->getOrderById($order['order_id']);
                if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                    // 用户是否支付成功
                    if ($message['result_code'] === 'SUCCESS') {
                        $orderdata=array('paytime'=>time(),'status'=>1);
                        $order->save($orderdata); // 保存订单
                        $groupdata =array('status'=>1,'paytime'=>time());
                        $grouporder->save($groupdata);
                        $redis = new Redis();
                        $con =$redis->connect('127.0.0.1',6379);
                        // 增加销量
                        $goodsinfo =(new Group())->getGoodsInfo([['id','=',$grouporder['goods_id']]],'*');
                        (new MallGroupsGoods())->where("id='".$grouporder['goods_id']."'")->save(array('sales'=>$goodsinfo['sales']+1,'stock'=>$goodsinfo['stock']-1));
                        if($con){
                            $redis->dec('groupgoods_'.$goodsinfo['id'],1);
                        }
                        // heads ==1 为拼团
                        if($grouporder['heads'] ==1){
                            $teamdata =array(
                                'order_id' =>$grouporder['id'],
                                'goods_id' =>$grouporder['goods_id'],
                                'openid' =>$grouporder['openid'],
                                'parent_id'=>0
                            );
                            if($grouporder['is_team']==0){
                                $teamdata['parent_id'] =$grouporder['team_id'];
                            }
                            $groupmodel =(new MallGroupsTeam());
                            $groupmodel->save($teamdata); // 记录拼团记录表

                            if($grouporder['team_id'] ==0 && $grouporder['is_team']==1){
                                $tinfo= $groupmodel->where([['order_id','=',$grouporder['id']],['goods_id','=',$grouporder['goods_id']],['openid','=',$grouporder['openid']]])->order('create_time desc')->find();
                                (new MallGroupsOrder())->where("id='".$grouporder['id']."'")->save(array('team_id'=>$tinfo['id']));
                            }

                            // 判断拼团是否满员
                            $buynum= $groupmodel->where("parent_id='".$grouporder['team_id']."'")->count();
                            if($grouporder['teamnum']==($buynum+1) && $grouporder['is_team']==0){
                                $groupmodel->where("parent_id='".$grouporder['team_id']."' or id='".$grouporder['team_id']."'")->save(array('status'=>1));
                                $grouporder->where("team_id='".$grouporder['team_id']."'")->save(array('endtime'=>time(),'success'=>1));
                            }
                        }else{
                            $grouporder->save(array('success'=>1));
                        }

                        // 返回用户钱包
                        if(!empty($grouporder['openid'])){
                            (new Member())->saveAccoutLog($grouporder['openid'],$grouporder['payprice'],4, '平台返现');
                        }

                        // 用户支付失败
                    } elseif ($message['result_code'] === 'FAIL') {
                        Log::error("用户支付失败");
                    }
                } else {
                    Log::error("通信失败");
                    return $fail('通信失败，请稍后再通知我');
                }
            }else if($message['attach']=='shopbzj'){ // 保证金
                if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                    // 用户是否支付成功
                    if ($message['result_code'] === 'SUCCESS') {
                        $orderdata = array('paytime' => time(), 'status' => 1);
                        $order->save($orderdata); // 保存订单
                        (new MallManager())->where([['openid','=',$order['openid']]])->save(['paystatus'=>1]);
                    }
                }
            }
            return true; // 返回处理完成
        });
        $response->send(); // return $response;
    }
}